package com.yonyou.pmclouds.safetyrectification.service.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.processor.*;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.consts.BillTypeConst;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.util.CommonFieldConst;
import com.yonyou.pmclouds.picture.entity.PictureParamVO;
import com.yonyou.pmclouds.picture.rmiitf.PictureRemoteService;
import com.yonyou.pmclouds.project.processor.ProjectBillUpdateForUpdate;
import com.yonyou.pmclouds.project.processor.UpdateBillCountForInsertProcessor;
import com.yonyou.pmclouds.safetyrectification.acceptrecord.entity.AcceptRecordVO;
import com.yonyou.pmclouds.safetyrectification.acceptrecord.service.IAcceptRecordMaintain;
import com.yonyou.pmclouds.safetyrectification.assignrecord.entity.AssignRecordVO;
import com.yonyou.pmclouds.safetyrectification.assignrecord.service.IAssignRecordMaintain;
import com.yonyou.pmclouds.safetyrectification.entity.SafetyRectiBillStatusConst;
import com.yonyou.pmclouds.safetyrectification.entity.SafetyRectificationVO;
import com.yonyou.pmclouds.safetyrectification.mapper.SafetyRectificationMapper;
import com.yonyou.pmclouds.safetyrectification.process.SafetyRectifyProjectLogPostProcess;
import com.yonyou.pmclouds.safetyrectification.rectificationrecord.entity.RectiRecordStatusConst;
import com.yonyou.pmclouds.safetyrectification.rectificationrecord.entity.RectificationRecordVO;
import com.yonyou.pmclouds.safetyrectification.rectificationrecord.service.IRectiRecordMaintain;
import com.yonyou.pmclouds.safetyrectification.rectificationrecord.service.IRectiRecordQuery;
import com.yonyou.pmclouds.safetyrectification.relationuser.entity.RelationUserVO;
import com.yonyou.pmclouds.safetyrectification.relationuser.service.IRelationUserMaintain;
import com.yonyou.pmclouds.safetyrectification.relationuser.service.IRelationUserQuery;
import com.yonyou.pmclouds.safetyrectification.service.ISafetyRectificationMaintain;
import com.yonyou.pmclouds.task.entity.TaskParamVO;
import com.yonyou.pmclouds.task.rmiitf.TaskRemoteService;
import org.apache.commons.collections.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;
import java.util.List;

/**
 * 安全整改事务接口实现类
 *
 * @author th
 * @date 2019/10/24 13:54
 */
@Service(interfaceClass = ISafetyRectificationMaintain.class, version = ApplicationConsts.APPLICATION_VERSION)
public class SafetyRectificationMaintainImpl implements ISafetyRectificationMaintain {
    /**
     * 安全整改更新的字段
     */
    private static final String[] UPDATE_FIELDS = {SafetyRectificationVO.BILL_STATUS, CommonFieldConst.MODIFYTIME,
            CommonFieldConst.MODIFIER, SafetyRectificationVO.RECTIFY_TIMES};
    /**
     * 整改记录更新的字段
     */
    private static final String[] RECTIFICATION_RECORD_UPDATE_FIELDS = {RectificationRecordVO.STATUS,
            CommonFieldConst.MODIFIER, CommonFieldConst.MODIFYTIME};

    @Autowired
    private SafetyRectificationMapper mapper;
    @Autowired
    private ProjectStatusCheckProcessor<SafetyRectificationVO> projectStatusCheckProcessor;
    @Autowired
    private PictureRemoteService pictureRemoteService;
    @Autowired
    private TaskRemoteService taskRemoteService;
    @Autowired
    private MobileTaskInsertProcessor<SafetyRectificationVO> taskInsertProcessor;
    @Autowired
    private MobileNoticeInsertProcessor<SafetyRectificationVO> noticeInsertProcessor;
    @Autowired
    private UpdateBillCountForInsertProcessor.UpdateBillCountForInsertProcessorFactory<SafetyRectificationVO> billCountFactory;
    @Autowired
    private ProjectBillUpdateForUpdate.ProjectBillForUpdateProcessorFactory<SafetyRectificationVO> billUpdateFactory;
    @Autowired
    private IAssignRecordMaintain assignRecordMaintain;
    @Autowired
    private IRelationUserMaintain relationUserMaintain;
    @Autowired
    private IRectiRecordMaintain rectiRecordMaintain;
    @Autowired
    private IAcceptRecordMaintain acceptRecordMaintain;
    @Autowired
    private IRectiRecordQuery rectiRecordQuery;
    @Autowired
    private IRelationUserQuery relationUserQuery;
    @Autowired
    private SafetyRectifyProjectLogPostProcess safetyRectifyProjectLogPostProcess;
    @Autowired
    private DocCenterProcessor docCenterProcessor;

    @Override
    public SafetyRectificationVO add(SafetyRectificationVO vo) throws BusinessException {
        vo.setOperation(SafetyRectificationVO.OPERATION_ADD);
        vo.setBillType(BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE);
        vo.setBillStatus(SafetyRectiBillStatusConst.STATUS_RECTIFING);
        vo.setRectifyTimes(0);

        SingleInsertBpTemplate<SafetyRectificationVO> bp = new SingleInsertBpTemplate<>(mapper);
        bp.addBeforeProcessor(new AuditInfoInsertProcessor<SafetyRectificationVO>());
        // 项目状态校验
        bp.addBeforeProcessor(projectStatusCheckProcessor);
        // 发送到整改人待办
        bp.addAfterProcessor(taskInsertProcessor);
        // 发送抄送人消息通知
        bp.addAfterProcessor(noticeInsertProcessor);
        // 更新项目下的单据数量
        bp.addAfterProcessor(billCountFactory.getProcessor(BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE));
        // 智能日志适配
        bp.addAfterProcessor(safetyRectifyProjectLogPostProcess);
        bp.insert(vo);

        // 新增一条交办记录
        AssignRecordVO assignRecordVO = generateAssignRecord(vo);
        assignRecordMaintain.add(assignRecordVO);
        // 保存抄送人
        List<RelationUserVO> relationUserList = generateRelationUsers(vo);
        relationUserMaintain.addVOs(relationUserList);
        // 保存图片
        PictureParamVO paramVO = new PictureParamVO(vo.getPkSafetyRectification(), vo.getPkProject(), BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE);
        pictureRemoteService.insertPictureForPub(vo, paramVO);

        return vo;
    }

    @Override
    public SafetyRectificationVO assign(AssignRecordVO assignRecordVO) throws BusinessException {
        SafetyRectificationVO safetyRectificationVO = mapper.getById(assignRecordVO.getPkBill());
        if (safetyRectificationVO == null)
            throw new BusinessException("未查询到安全整改");
        ;

        safetyRectificationVO.setOperation(SafetyRectificationVO.OPERATION_ASSIGN);
        safetyRectificationVO.setCreatorName(assignRecordVO.getSafetyRectifyCreatorName());

        // 新增交办记录
        assignRecordVO.setPkProject(safetyRectificationVO.getPkProject());
        assignRecordVO.setSrcBillType(BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE);
        assignRecordVO.setLastBillTime(safetyRectificationVO.getDeadline());
        assignRecordMaintain.add(assignRecordVO);

        // 更新安全整改，整改人、整改期限
        String oldPkRectifictioner = safetyRectificationVO.getPkRectificationer();
        safetyRectificationVO.setPkRectificationer(assignRecordVO.getAssignUser());
        safetyRectificationVO.setRectificationerName(assignRecordVO.getAssignPersonName());
        Date updateDeadline = assignRecordVO.getThisBillTime();
        if (updateDeadline != null) {
            safetyRectificationVO.setDeadline(updateDeadline);
        }
        setRelationUser(safetyRectificationVO);
        String[] updateFields = {SafetyRectificationVO.PK_RECTIFICATIONER, SafetyRectificationVO.DEADLINE,
                CommonFieldConst.MODIFIER, CommonFieldConst.MODIFYTIME};
        SingleUpdateBpTemplate<SafetyRectificationVO> bp = new SingleUpdateBpTemplate<>(mapper, updateFields);
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<SafetyRectificationVO>());
        bp.addAfterProcessor(noticeInsertProcessor);
        bp.addAfterProcessor(safetyRectifyProjectLogPostProcess);
        bp.update(safetyRectificationVO);

        // 给整改人发送待办
        TaskParamVO paramVO = new TaskParamVO(oldPkRectifictioner, assignRecordVO.getAssignUser(), null);
        taskRemoteService.insertWithBuziVO(safetyRectificationVO, paramVO);

        return safetyRectificationVO;
    }

    @Override
    public SafetyRectificationVO rectify(RectificationRecordVO recordVO) throws BusinessException {
        SafetyRectificationVO safetyRectificationVO = mapper.getById(recordVO.getPkSafetyRectification());
        if (safetyRectificationVO == null)
            throw new BusinessException("未查询到安全整改");

        // 新增整改记录
        recordVO.setPkProject(safetyRectificationVO.getPkProject());
        recordVO.setStatus(RectiRecordStatusConst.STATUS_INIT);
        rectiRecordMaintain.add(recordVO);

        // 更新安全整改
        // 设置抄送人、创建人名称，消息通知需要
        safetyRectificationVO.setCreatorName(recordVO.getSafetyRectifyCreatorName());
        setRelationUser(safetyRectificationVO);
        safetyRectificationVO.setOperation(SafetyRectificationVO.OPERATION_RECTIFY);
        safetyRectificationVO.setBillStatus(SafetyRectiBillStatusConst.STATUS_ACCEPTING);
        safetyRectificationVO.setRectifyTimes(safetyRectificationVO.getRectifyTimes() + 1);
        updateBill(safetyRectificationVO, UPDATE_FIELDS);

        // 发送待办到验收人
        TaskParamVO paramVO = new TaskParamVO(safetyRectificationVO.getPkRectificationer(),
                safetyRectificationVO.getCreator(), null);
        taskRemoteService.insertWithBuziVO(safetyRectificationVO, paramVO);

        return safetyRectificationVO;
    }

    /**
     * 安全整改查询抄送人
     *
     * @param safetyRectificationVO
     */
    private void setRelationUser(SafetyRectificationVO safetyRectificationVO) throws BusinessException {
        List<RelationUserVO> relationUserList = relationUserQuery.getByPkBill(safetyRectificationVO.getPkSafetyRectification());
        safetyRectificationVO.setRelationUserList(relationUserList);
    }

    @Override
    public SafetyRectificationVO rectifyAgain(AcceptRecordVO recordVO) throws BusinessException {
        SafetyRectificationVO safetyRectificationVO = mapper.getById(recordVO.getPkBill());
        safetyRectificationVO.setOperation(SafetyRectificationVO.OPERATION_NO_PASS);

        // 新增验收记录
        recordVO.setPkProject(safetyRectificationVO.getPkProject());
        acceptRecordMaintain.add(recordVO);

        // 更新安全整改
        safetyRectificationVO.setCreatorName(recordVO.getSafetyRectifyCreatorName());
        safetyRectificationVO.setBillStatus(SafetyRectiBillStatusConst.STATUS_RECTIFING);
        setRelationUser(safetyRectificationVO);
        updateBill(safetyRectificationVO, UPDATE_FIELDS);

        // 更新整改记录
        RectificationRecordVO rectificationRecordVO = rectiRecordQuery.getById(recordVO.getPkRectificationRecord());
        rectificationRecordVO.setStatus(RectiRecordStatusConst.STATUS_NOT_PASS);
        rectiRecordMaintain.update(rectificationRecordVO, RECTIFICATION_RECORD_UPDATE_FIELDS);

        // 发送待办到整改人
        TaskParamVO paramVO = new TaskParamVO(safetyRectificationVO.getCreator(),
                safetyRectificationVO.getPkRectificationer(), null);
        taskRemoteService.insertWithBuziVO(safetyRectificationVO, paramVO);

        return safetyRectificationVO;
    }

    @Override
    public SafetyRectificationVO pass(SafetyRectificationVO rectificationVO) throws BusinessException {
        SafetyRectificationVO vo = mapper.getById(rectificationVO.getPkSafetyRectification());
        vo.setOperation(SafetyRectificationVO.OPERATION_PASS);

        // 更新整改记录
        List<RectificationRecordVO> rectificationRecordList = rectiRecordQuery.getByBillAndStatus(
                rectificationVO.getPkSafetyRectification(), RectiRecordStatusConst.STATUS_INIT);
        if (CollectionUtils.isNotEmpty(rectificationRecordList)) {
            RectificationRecordVO rectificationRecordVO = rectificationRecordList.get(0);
            rectificationRecordVO.setStatus(RectiRecordStatusConst.STATUS_PASS);
            rectiRecordMaintain.update(rectificationRecordVO, RECTIFICATION_RECORD_UPDATE_FIELDS);
        }

        // 更新安全整改
        vo.setCreatorName(rectificationVO.getCreatorName());
        vo.setBillStatus(SafetyRectiBillStatusConst.STATUS_END);
        setRelationUser(vo);
        updateBill(vo, UPDATE_FIELDS);

        docCenterProcessor.process(vo,null);
        // 完成待办
        taskRemoteService.finishTask(rectificationVO.getPkSafetyRectification(), vo.getCreator(),
                SafetyRectiBillStatusConst.STATUS_END);

        return vo;
    }

    /**
     * 更新安全整改
     *
     * @param vo
     * @param fields
     */
    private void updateBill(SafetyRectificationVO vo, String[] fields) throws BusinessException {
        SingleUpdateBpTemplate<SafetyRectificationVO> bp = new SingleUpdateBpTemplate<>(mapper, fields);
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<SafetyRectificationVO>());
        bp.addAfterProcessor(noticeInsertProcessor);
        bp.addAfterProcessor(billUpdateFactory.getProcessor(BillTypeConst.SAFETY_RECTIFICATION_BILLTYPE));

        bp.update(vo);
    }

    /**
     * 生成抄送人，给pkBill赋值
     *
     * @param vo
     * @return
     */
    private List<RelationUserVO> generateRelationUsers(SafetyRectificationVO vo) {
        List<RelationUserVO> relationUserList = vo.getRelationUserList();
        if (CollectionUtils.isEmpty(relationUserList))
            return relationUserList;

        String pkBill = vo.getPkSafetyRectification();
        for (RelationUserVO userVO : relationUserList) {
            userVO.setPkBill(pkBill);
        }

        return relationUserList;
    }

    /**
     * 生成交办记录
     *
     * @param vo
     * @return
     */
    private AssignRecordVO generateAssignRecord(SafetyRectificationVO vo) {
        AssignRecordVO recordVO = new AssignRecordVO();
        recordVO.setAssignUser(vo.getPkRectificationer());
        recordVO.setPkBill(vo.getPkSafetyRectification());
        recordVO.setPkProject(vo.getPkProject());
        recordVO.setLastBillTime(vo.getDeadline());
        recordVO.setSrcBillType(vo.getBillType());

        return recordVO;
    }

    @Override
    public SafetyRectificationVO update(SafetyRectificationVO vo) throws BusinessException {
        SingleUpdateBpTemplate<SafetyRectificationVO> bp = new SingleUpdateBpTemplate<>(mapper, UPDATE_FIELDS);
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<SafetyRectificationVO>());

        return bp.update(vo);
    }

}
